#include "framework/testutil.h"
#include "frontend/parser.h"
#include <iostream>

RUN_ALL_TESTS();

using namespace mspc;
/*
void print_ast(const mspc::File& file, const std::string& test_name) {
    std::cout << "AST for " << test_name << ":" << std::endl;
    std::cout << "  Syntax: " << file.syntax_version << std::endl;
    std::cout << "  Package: " << file.package_name << std::endl;
    std::cout << "  Structs: " << file.structs.size() << std::endl;
    std::cout << "  Messages: " << file.messages.size() << std::endl;
    std::cout << "  Enums: " << file.enums.size() << std::endl;
}
*/

// 测试用例实现
TEST("TestParser", "test_basic_parsing") {

    mspc::Parser p(mspc::TokenContainer(""));
    ASSERT_TRUE(!p.has_errors());

    // 测试1：空文件
    {
        std::string source = "";
        auto lexer = mspc::Lexer(source, "empty_test");
        auto tokens = lexer.tokenize();
        mspc::Parser parser(tokens);
        auto file = parser.parse();
        ASSERT_TRUE(file != nullptr);
        ASSERT_EQ(file->structs.size(), size_t(0));
        ASSERT_EQ(file->messages.size(), size_t(0));
    }

    // 测试2：只有语法声明
    {
        std::string source = R"(
syntax = "msp/v1";
)";
        auto lexer = mspc::Lexer(source, "syntax_only");
        auto tokens = lexer.tokenize();
        mspc::Parser parser(tokens);
        auto file = parser.parse();
        ASSERT_TRUE(file != nullptr);
        ASSERT_EQ(file->syntax_version, std::string("msp/v1"));
    }
}

TEST("TestParser", "test_struct_parsing") {

    std::string source = R"(
syntax = "msp/v1";
package test;

struct User {
    string name = 1;
    int32 age = 2 : 0;
    bool active = 3 : true;
}

struct Address {
    string street = 1;
    string city = 2 : "Unknown";
    string country = 3;
}
)";

    auto lexer = mspc::Lexer(source, "struct_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();

    ASSERT_EQ(file->structs.size(), size_t(2));
    ASSERT_EQ(file->structs[0]->name, std::string("User"));
    ASSERT_EQ(file->structs[0]->fields.size(), size_t(3));
    ASSERT_EQ(file->structs[1]->name, std::string("Address"));

    // 验证字段
    const auto& user_fields = file->structs[0]->fields;
    ASSERT_EQ(user_fields[0]->name, std::string("name"));
    ASSERT_EQ(user_fields[0]->type, std::string("string"));
    ASSERT_EQ(user_fields[0]->number, uint32_t(1));

    ASSERT_EQ(user_fields[1]->name, std::string("age"));
    ASSERT_EQ(user_fields[1]->type, std::string("int32"));
    ASSERT_EQ(user_fields[1]->default_value, std::string("0"));
}

TEST("TestParser", "test_message_parsing") {

    std::string source = R"(
syntax = "msp/v1";

message LoginRequest {
    id = 1001;
    string username = 1;
    string password = 2;
}

message LoginResponse {
    id = 1002;
    bool success = 1 : false;
    string token = 2 : "";
    int32 user_id = 3;
}
)";

    auto lexer = mspc::Lexer(source, "message_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    ASSERT_EQ(file->messages.size(), size_t(2));

    // 验证消息ID
    ASSERT_EQ(file->messages[0]->id, uint32_t(1001));
    ASSERT_EQ(file->messages[1]->id, uint32_t(1002));

    // 验证字段
    const auto& response_fields = file->messages[1]->fields;
    ASSERT_EQ(response_fields[0]->name, std::string("success"));
    ASSERT_EQ(response_fields[0]->default_value, std::string("false"));
    // ASSERT_TRUE(response_fields[0]->is_optional());
}

TEST("TestParser", "test_enum_parsing") {

    std::string source = R"(
syntax = "msp/v1";

enum UserStatus {
    ACTIVE = 1;
    INACTIVE = 2;
    PENDING = 3;
}

enum Priority {
    LOW = 1;
    MEDIUM = 2;
    HIGH = 3;
    URGENT = 4;
}
)";

    auto lexer = mspc::Lexer(source, "enum_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    ASSERT_EQ(file->enums.size(), size_t(2));
    ASSERT_EQ(file->enums[0]->values.size(), size_t(3));
    ASSERT_EQ(file->enums[1]->values.size(), size_t(4));

    // 验证枚举值
    const auto& status_values = file->enums[0]->values;
    ASSERT_EQ(status_values[0]->name, std::string("ACTIVE"));
    ASSERT_EQ(status_values[0]->value, int32_t(1));
    ASSERT_EQ(status_values[1]->name, std::string("INACTIVE"));
    ASSERT_EQ(status_values[1]->value, int32_t(2));
}

TEST("TestParser", "test_import_package") {

    std::string source = R"(
syntax = "msp/v2";
package com.example.chat;

import "common.msp";
import "types.msp";
)";

    auto lexer = mspc::Lexer(source, "import_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    ASSERT_EQ(file->syntax_version, std::string("msp/v2"));
    ASSERT_EQ(file->package_name, std::string("com.example.chat"));
    ASSERT_EQ(file->imports.size(), size_t(2));
    ASSERT_EQ(file->imports[0]->filename, std::string("common.msp"));
    ASSERT_EQ(file->imports[1]->filename, std::string("types.msp"));
}

TEST("TestParser", "test_error_handling") {

    // 测试1：缺少分号
    {
        std::string source = R"(
message Test {
    id = 1001
    string name = 1  // 缺少分号
}
)";
        mspc::Lexer lexer(source, "error_test1");
        auto tokens = lexer.tokenize();
        mspc::Parser parser(tokens);
        auto file = parser.parse();

        ASSERT_TRUE(parser.has_errors());
    }

    // 测试2：缺少消息ID
    {
        std::string source = R"(
message InvalidMessage {
    string name = 1;  // 缺少id字段
}
)";
        mspc::Lexer lexer(source, "error_test2");
        auto tokens = lexer.tokenize();
        mspc::Parser parser(tokens);
        auto file = parser.parse();

        ASSERT_TRUE(parser.has_errors());
    }

    // 测试3：重复字段编号
    {
        std::string source = R"(
message Test {
    id = 1001;
    string field1 = 1;
    int32 field2 = 1;  // 重复编号
}
)";
        mspc::Lexer lexer(source, "error_test3");
        auto tokens = lexer.tokenize();
        mspc::Parser parser(tokens);
        auto file = parser.parse();

        // 注意：重复编号检查应该在语义分析阶段，不是语法分析阶段
        ASSERT_TRUE(!parser.has_errors());
    }
}
TEST("TestParser", "test_nested_messages") {

    std::string source = R"(
syntax = "msp/v1";

message OuterMessage {
    id = 1001;
    string outer_field = 1;

    message InnerMessage {
        id = 1002;
        int32 inner_field = 1;
    }

    enum Status {
        OK = 1;
        ERROR = 2;
    }

    InnerMessage inner = 2;
    Status status = 3;
}
)";

    auto lexer = mspc::Lexer(source, "nested_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    ASSERT_EQ(file->messages.size(), size_t(1));
    const auto& outer = file->messages[0];
    ASSERT_EQ(outer->nested_messages.size(), size_t(1));
    ASSERT_EQ(outer->nested_enums.size(), size_t(1));

    const auto& inner = outer->nested_messages[0];
    ASSERT_EQ(inner->name, std::string("InnerMessage"));
    ASSERT_EQ(inner->id, uint32_t(1002));
}

TEST("TestParser", "test_field_options") {

    std::string source = R"(
syntax = "msp/v1";

message Config {
    id = 1001;
    string name = 1 : "unknown";
    int32 port = 2 : 8080;
    bool enabled = 3 : false;
    repeated string test = 4;
}
)";

    auto lexer = mspc::Lexer(source, "options_test");
    auto tokens = lexer.tokenize();
    // std::cout << "tokens count:" << tokens.size() << std::endl;
    // tokens.print();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    ASSERT_EQ(file->messages.size(), size_t(1));
    auto& message = file->messages[0];
    ASSERT_TRUE(message != nullptr);
    ASSERT_EQ(message->fields.size(), size_t(4));
    ASSERT_EQ(message->fields[0]->default_value, "unknown");
    ASSERT_EQ(message->fields[1]->default_value, "8080");
    ASSERT_EQ(message->fields[2]->default_value, "false");
    ASSERT_TRUE(!message->fields[2]->is_repeated());
    ASSERT_TRUE(message->fields[3]->is_repeated());
}

TEST("TestParser", "test_complex_example") {

    std::string source = R"(
syntax = "msp/v1";
package chat.example;

import "common.msp";

struct User {
    string name = 1;
    int32 age = 2 : 0;
    string email = 3 : "";
}

enum MessageType {
    TEXT = 1;
    IMAGE = 2;
    FILE = 3;
}

message ChatMessage {
    id = 1001;
    User sender = 1;
    string content = 2;
    MessageType type = 3 : TEXT;
    int64 timestamp = 4;
    repeated string attachments = 5;
}

message ChatRoom {
    id = 1002;
    string name = 1;
    repeated User members = 2;
    repeated ChatMessage messages = 3;
}
)";

    auto lexer = mspc::Lexer(source, "complex_test");
    auto tokens = lexer.tokenize();
    mspc::Parser parser(tokens);
    auto file = parser.parse();
    // 验证整体结构
    ASSERT_EQ(file->package_name, std::string("chat.example"));
    ASSERT_EQ(file->imports.size(), size_t(1));
    ASSERT_EQ(file->structs.size(), size_t(1));
    ASSERT_EQ(file->enums.size(), size_t(1));
    ASSERT_EQ(file->messages.size(), size_t(2));

    // 验证复杂字段类型
    const auto& chat_message = file->messages[0];
    ASSERT_EQ(chat_message->fields[0]->type, std::string("User"));
    ASSERT_EQ(chat_message->fields[2]->type, std::string("MessageType"));
    ASSERT_TRUE(chat_message->fields[4]->is_repeated());

    // print_ast(*file, "Complex Example");
}
